package com.cc8w.home.service;

import com.cc8w.entity.UserEntity;
import com.cc8w.home.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service("userService")
@Transactional
public class UserService {

    @Autowired
    @Qualifier("userMapper")
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 常规查数据库
     */
    public UserEntity queryUserByUserName(String userName){
        return userMapper.queryUserByUserName(userName);
    }

    /**
     * 先查询缓存是否有值(在高并发下有缓存穿透问题)
     */
    public UserEntity queryUserByName(String userName){
        //1.先查缓存
        UserEntity user = null;
        user  = (UserEntity)redisTemplate.opsForValue().get("queryUserByName");


        /**
         * 一般缓存的判断
         */
        if(null == user ){
            System.out.println("查数据库...");
            user = userMapper.queryUserByUserName(userName);
            redisTemplate.opsForValue().set("queryUserByName",user);
        }else{
            System.out.println("查缓存...");
        }
        return user;
    }

    /**
     * 先查询缓存(解决高并发下的缓存穿透问题)
     * 1.主要方法加同步锁
     */
    public /*synchronized*/ UserEntity queryUserByUname(String userName){
        UserEntity user = null;
        user  = (UserEntity)redisTemplate.opsForValue().get("queryUserByName");

        /**
         * 双重检测锁
         */
        if(null == user ){

            synchronized (this){
                user  = (UserEntity)redisTemplate.opsForValue().get("queryUserByName");
                if(null == user ){
                    System.out.println("查数据库...");
                    user = userMapper.queryUserByUserName(userName);
                    redisTemplate.opsForValue().set("queryUserByName",user);
                }else{
                    System.out.println("查缓存...");
                }
            }

        }else{
            System.out.println("查缓存...");
        }
        return user;
    }



}
